using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

#if !SUDOKU_MASTER
using Microsoft.Advertising.Mobile.Xna;
#endif

using Services;
using Sudoku.Utilities;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Controls;

namespace Sudoku
{
	public class Sudoku : Game
	{
		GraphicsDeviceManager graphics;
		bool screenLocked;

#if !SUDOKU_MASTER
		AdManager adManager;
#endif

		public Sudoku()
		{
			graphics = new GraphicsDeviceManager(this);
			Content.RootDirectory = "Content";
			
			// Frame rate is 30 fps by default for Windows Phone.
			TargetElapsedTime = TimeSpan.FromTicks(333333);

#if WINDOWS || XBOX
#else
			graphics.IsFullScreen = true;
#endif
            graphics.PreferredBackBufferWidth = 480;
			graphics.PreferredBackBufferHeight = 800;

			IsMouseVisible = true;
			try
			{
				PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
			}
			catch (InvalidOperationException)
			{ 
				//Always get this, according to microsoft MSDN
			}

#if !SUDOKU_MASTER
			adManager = new AdManager(this, "f600e48d-4142-4b9c-8bf9-eb6a180ded21");
			adManager.DrawOrder = (int)ComponentOrders.ADS;
			Components.Add(adManager);
			Services.AddService(typeof(AdManager), adManager);
#endif
		}

		protected override void Initialize()
		{
			this.Activated += new EventHandler<EventArgs>(OnActive);
			this.Deactivated += new EventHandler<EventArgs>(OnDeactive);
			screenLocked = false;

			FontLibrary Fonts;
			TextureLibrary Textures;
			SoundLibrary Sounds;
			FileIOService FileIO;
			ScoreService HighScores;
			SaveService SaveService;

			//Load Font Elements
			Fonts = new FontLibrary(Content);
			Services.AddService(typeof(FontLibrary), Fonts);

			//Load Texture Element
			Textures = new TextureLibrary(Content);
			Services.AddService(typeof(TextureLibrary), Textures);

			//Load Audio Element
			Sounds = new SoundLibrary(Content);
			Services.AddService(typeof(SoundLibrary), Sounds);

			//Load IOFileService
			FileIO = new FileIOService();
			Services.AddService(typeof(FileIOService), FileIO);

			//Load HighScores
			HighScores = new ScoreService(this);
			Services.AddService( typeof(IScoreService), HighScores);

			//Load SaveService
			SaveService = new SaveService(this);
			Services.AddService(typeof(ISaveService), SaveService);

			if(Guide.IsTrialMode)
			{
				TrialService Trial = new TrialService();
				Services.AddService(typeof(ITrialService), Trial);
			}

			StateManagement.StateManager.Loader(this);

			base.Initialize();
		}

		private void OnActive(object sender, EventArgs args)
		{
			screenLocked = false;
		}

		private void OnDeactive(object sender, EventArgs e)
		{
			screenLocked = true;
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Enabled;
			}
			catch (InvalidOperationException)
			{
				//Always get this, according to microsoft MSDN
			} 
			
			Services.RemoveService(typeof(FontLibrary));
			Services.RemoveService(typeof(TextureLibrary));
			Services.RemoveService(typeof(SoundLibrary));
			Services.RemoveService(typeof(ScoreService));
			Services.RemoveService(typeof(ISaveService));
			Services.RemoveService(typeof(FileIOService));

			if (Guide.IsTrialMode) Services.RemoveService(typeof(ITrialService));

			base.Dispose(disposing);
		}

		protected override void Update(GameTime gameTime)
		{
			if (!screenLocked) base.Update(gameTime);
		}

		protected override void Draw(GameTime gameTime)
		{
			if (!screenLocked)
			{
				GraphicsDevice.Clear(Color.White);
				base.Draw(gameTime);
			}
		}

		internal void Draw()
		{
			this.Draw(new GameTime());
		}
	}
    
}
